<?php

namespace App\Services\Admin;

use App\Models\ClassBaseInfo;
use App\Models\GroupClass as GroupClassModel;
use App\Models\GroupClassInfo as GroupClassInfoModel;
use App\Models\GroupClassInfo;
use Illuminate\Support\Facades\DB;

class GroupClass extends Base
{
    public static function lists()
    {
        $input = request()->all();

        $where = [];

        if(!empty($input['group_class_name']))$where[] = ['group_class_name','like', '%'.$input['group_class_name'].'%'];
        if(!empty($input['store_id'])) $where[] = ['store_id', $input['store_id']];

        return GroupClassModel::with(['group_class_info','store'])->where($where)->orderBy('id', 'desc')->paginate(15);
    }

    public static function camp_info($id)
    {
        return ClassBaseInfo::with(['teacher','group_class_info'=>function($query)use($id){
            $query->where('group_class_id',$id)->orderBy('plan_date','asc');
        },'classsroom','class_base'])->whereHas('group_class_info',function ($query)use($id){
            $query->where('group_class_id',$id);
        });
    }

    public static function info($id)
    {
        //dd((new GroupClassModel)->where('id', $id)->first());
        return (new GroupClassModel)->where('id', $id)->first();
    }

    public static function group_class_info($id)
    {
        return (new GroupClassInfo())->where('group_class_id', $id)->groupBy('class_base_info_id');
    }

    public static function add($param = [])
    {
        //开启事务
        DB::beginTransaction();
        try{
            $registration_time = "{$param['registration_time']} 23:59:59";
            $registration_start_time = "{$param['registration_start_time']} 00:00:00";

            $start_time = "{$param['start_time']} 00:00:00";
            $end_time = "{$param['end_time']} 23:59:59";

            $insert['store_id'] = $param['store_id'];
            $insert['group_class_name'] = $param['group_class_name'];
            $insert['group_class_price'] = $param['group_class_price'];
            //$param['remedial_teaching_number']
            $insert['remedial_teaching_number'] = $param['remedial_teaching_number'];
            $insert['buy_number'] = $param['buy_number'];
            $insert['trx'] = $param['trx'];
            $insert['make_up_rules'] = $param['make_up_rules'];
            $insert['crowd'] = $param['crowd'];
            $insert['points'] = $param['points'];
            if(isset($param['cove_img']))$insert['cove_img'] = $param['cove_img'];
            $insert['start_time'] = $start_time;
            $insert['end_time'] = $end_time;
            $insert['registration_time'] = $registration_time;
            $insert['registration_start_time'] = $registration_start_time;

            $reservation_info = Reservation::lists()->whereIn('id', explode(",",$param['class_base_info_id']))->get();

            $insert['class_time_info'] = Reservation::check_class_time($reservation_info->toArray());

            $group_class_id = (new GroupClassModel)->insertGetId($insert);

            if($reservation_info->isEmpty())throw new \Exception('请选择课程安排');

            $day = self::diff_between_two_days($start_time, $end_time);

            $insert_get_week_days = [];

            //总时长
            $class_hour = 0;

            //是否有老师上课
            $teacher_bool_info = 1;

            foreach ($reservation_info as $k=>$v){

                $teacher_bool_info = Reservation::class_bass_info_teacher_arr($v->class_base_info_teacher->toArray());

                if(empty($teacher_bool_info['id'])){
                    $teacher_bool_info = 0;
                    break;
                }

                $get_week_days = self::get_week_days($param['start_time'], [Reservation::class_bass_week($v['class_week'])], $day);

                $input['class_base_info_id'] = $v->id;
                $input['get_week_days'] = $get_week_days;
                $input['class_time'] = $v->class_time;;

                $class_hour += count($get_week_days) * $v['class_duration'];

                $insert_get_week_days[] = $input;

            }

            if(!$teacher_bool_info)throw new \Exception('選擇的camp沒老師上課，請先去設置好在添加camp');

            //更新总时长
            $class_hour_update['class_hour'] = $class_hour;
            (new GroupClassModel)->where('id', $group_class_id)->update($class_hour_update);

            if(!empty($insert_get_week_days)) {

                $group_class_info_insert = [];

                foreach ($insert_get_week_days as $v){

                    $class_start_time = explode("~", $v['class_time']);

                    for ($i = 0; $i < count($v['get_week_days']); $i++) {

                        $input = [];
                        $input['class_base_info_id'] = $v['class_base_info_id'];
                        $input['group_class_id'] = $group_class_id;
                        //$input['remedial_teaching_number'] = $param['remedial_teaching_number'];
                        $input['created_at'] = date('Y-m-d h:i:s');
                        $input['plan_date'] = "{$v['get_week_days'][$i]} {$class_start_time[0]}";

                        $group_class_info_insert[] = $input;
                    }

                }

                if(empty($group_class_info_insert))throw new \Exception('該時間範圍沒有camp課上，請擴大時間範圍');

                (new GroupClassInfo())->insert($group_class_info_insert);

            }else{

                throw new \Exception('选择的时间范围没有该选择课程，请正确选择上课时间');

            }

            DB::commit();
        }catch (\Exception $e) {

            //接收异常处理并回滚
            DB::rollBack();

            return ['bool'=>false, 'message'=>$e->getMessage()];

        }

        return ['bool'=>true, 'message'=>''];

    }

    public static function edit($id , $param=[])
    {
        //开启事务
        DB::beginTransaction();
        try{
            $registration_time = "{$param['registration_time']} 23:59:59";
            $registration_start_time = "{$param['registration_start_time']} 00:00:00";

            $start_time = "{$param['start_time']} 00:00:00";
            $end_time = "{$param['end_time']} 23:59:59";

            $insert['store_id'] = $param['store_id'];
            $insert['group_class_name'] = $param['group_class_name'];
            $insert['group_class_price'] = $param['group_class_price'];
            $insert['remedial_teaching_number'] = $param['remedial_teaching_number'];
            $insert['buy_number'] = $param['buy_number'];
            $insert['trx'] = $param['trx'];
            $insert['make_up_rules'] = $param['make_up_rules'];
            $insert['crowd'] = $param['crowd'];
            $insert['points'] = $param['points'];
            if(isset($param['cove_img']))$insert['cove_img'] = $param['cove_img'];
            $insert['start_time'] = $start_time;
            $insert['end_time'] = $end_time;
            $insert['registration_start_time'] = $registration_start_time;
            $insert['registration_time'] = $registration_time;

            $reservation_info = Reservation::lists()->whereIn('id', explode(",",$param['class_base_info_id']))->get();

            $insert['class_time_info'] = Reservation::check_class_time($reservation_info->toArray());
            //dd($insert);
            (new GroupClassModel)->where('id', $id)->update($insert);

            if(empty($reservation_info))throw new \Exception('请选择课程安排');

            $day = self::diff_between_two_days($start_time, $end_time);

            $insert_get_week_days = [];

            //总时长
            $class_hour = 0;

            //是否有老师上课
            $teacher_bool_info = 1;

            foreach ($reservation_info as $v){

                $teacher_bool_info = Reservation::class_bass_info_teacher_arr($v->class_base_info_teacher->toArray());

                if(empty($teacher_bool_info['id'])){
                    $teacher_bool_info = 0;
                    break;
                }

                $get_week_days = self::get_week_days($param['start_time'], [Reservation::class_bass_week($v['class_week'])], $day);

                $input['class_base_info_id'] = $v->id;
                $input['get_week_days'] = $get_week_days;
                $input['class_time'] = $v->class_time;

                $class_hour += count($get_week_days) * $v['class_duration'];

                $insert_get_week_days[] = $input;
            }

            if(!$teacher_bool_info)throw new \Exception('選擇的camp沒老師上課，請先去設置好在添加camp');

            //更新总时长
            $class_hour_update['class_hour'] = $class_hour;
            (new GroupClassModel)->where('id', $id)->update($class_hour_update);

            (new GroupClassInfo())->where('group_class_id', $id)->delete();

            if(!empty($insert_get_week_days)) {

                $group_class_info_insert = [];

                foreach ($insert_get_week_days as $v){

                    $class_start_time = explode("~", $v['class_time']);

                    for ($i = 0; $i < count($v['get_week_days']); $i++) {

                        $input = [];
                        $input['class_base_info_id'] = $v['class_base_info_id'];
                        $input['group_class_id'] = $id;
                        //$input['remedial_teaching_number'] = $param['remedial_teaching_number'];
                        $input['updated_at'] = date('Y-m-d h:i:s');
                        $input['plan_date'] = "{$v['get_week_days'][$i]} {$class_start_time[0]}";

                        $group_class_info_insert[] = $input;

                    }

                }

                if(empty($group_class_info_insert))throw new \Exception('該時間範圍沒有camp課上，請擴大時間範圍');

                (new GroupClassInfo())->insert($group_class_info_insert);

            }else{

                throw new \Exception('选择的时间范围没有该选择课程，请正确选择上课时间');

            }

            DB::commit();
        }catch (\Exception $e) {
            //接收异常处理并回滚
            DB::rollBack();

            return ['bool'=>false, 'message'=>$e->getMessage()];
        }


        return ['bool'=>true, 'message'=>''];
    }

    public static function del($id)
    {
        (new GroupClassModel)->where('id', $id)->delete();
        (new GroupClassInfoModel())->where('group_class_id', $id)->delete();

    }

    /**
     * 求两个日期之间相差的天数
     * (针对1970年1月1日之后，求之前可以采用泰勒公式)
     * @param string $day1
     * @param string $day2
     * @return number
     */
    public static function diff_between_two_days($start_date, $end_date)
    {
        return floor((strtotime($end_date)-strtotime($start_date))/86400);
    }


    /**
     * 计算有多少个周几
     */
    /**
     * @desc: 根据开始时间和每周的周期计算出天数范围内的所有时间段
     * @param: $start  开始时间
     * @param: $weeks  每周的星期 如每周的周一,周二  对应值 [1,2]
     * @parma: $days   需要计算出多少天
     * @return: Array
     */
    public static function get_week_days($start, $weeks = [], $days = 1){

        $datas = [];

        $date = $start;

        $counts = 0;

        while($counts <= $days){

            $week = date('N', strtotime($date));

            $counts++;

            if(in_array($week,$weeks)){
                array_push($datas,$date);
            }

            $date = date('Y-m-d', strtotime('+1 day', strtotime($date)));

        }

        return $datas;

    }
}
